<?php

use Doraemon\service\statSign\Basic as statSign;
use Doraemon\tools\ActionLog;
use Doraemon\tools\Youzan;
use hhz\constant\redis\redisKeys;
use Hhz\Redis\newCache;

class GoodsListAction extends ActionPlugin
{
    public const USER_LEVEL = self::LEVEL_NOTHING;

    private $actFrom = 'app';

    /**
     * @throws Exception
     */
    public function main()
    {
        $this->actFrom = $this->getRequest()->getQuery('act_from', 'app');
        if (date('Y-m-d H:i:s') < '2022-10-11') {
            ActionLog::log($this->uid, ['pageName' => 'subsidy_order', 'act_from' => $this->actFrom], 'subsidy_day');
        } else {
            ActionLog::log($this->uid, ['pageName' => 'subsidy_day', 'act_from' => $this->actFrom], 'subsidy_day');
        }
        $redis = new newCache(redisKeys::KEY_B_CACHE_SUPER_SUBSIDY_DAY_GOODS);
        $data = $redis->getCache();

        $seckillData = $data['seckill_data'];
        $onlineData = $data['online_data'];
        if ($onlineData) {
            shuffle($onlineData);
        }
        /*商品展示规则：
               今日秒杀列表：秒杀列表中秒杀时间为当日 & 秒杀时间已开始但秒杀库存 > 0的商品
               明日秒杀列表：秒杀列表中秒杀开始时间为第二天的商品
               补贴列表：补贴列表中的商品（若该商品也在秒杀列表中，则秒杀库存 = 0时，才展示该商品）
        */
        $onSaleSeckill = [];
        $tomorrowSeckill = [];
        $allSeckill = [];
        $today = strtotime(date('Y-m-d'));
        $tomorrow = $today + 86400;
        foreach ($seckillData as $row) {
            $itemId = $row['item_id'];
            $row['statSign'] = statSign::genStatSign(statSign::MODULE_SUBSIDY_DAY_BANNER, [
                statSign::EXTEND_KEY_OBJ_ID => $row['alias'],
                statSign::EXTEND_KEY_ACTIVITY_NAME => 'subsidy_day'
            ], ['activity_name' => 'subsidy_day', 'title' => $row['title'], 'act_from' => $this->actFrom]);
            if (strtotime($row['begin_time']) < ($tomorrow + 86400)) {
                //暂停使用
//                $seckillInfo = $this->getSecKillInfo($row['seckill_id']);
//                $row['stock'] = $seckillInfo['stock'] ?? 0;
                $row['open_wechat_mini_link'] = $this->getLink($row['original_link'], $row['wechat_mini_link'], $row['share_wechat_mini_link']);
                if (strtotime($row['begin_time']) < $tomorrow) {
                    //今天秒杀都都展示。昨天以前的秒杀有库存都才展示，没有库存，不展示。
                    if (strtotime($row['begin_time']) >= $today || (strtotime($row['begin_time']) < $today && $row['stock'] > 0)) {
                        $onSaleSeckill[$itemId] = $row;
                    }
                } else if (strtotime($row['begin_time']) >= $tomorrow && strtotime($row['begin_time']) < ($tomorrow + 86400)) {
                    $tomorrowSeckill[$itemId] = $row;
                }
            }
            $allSeckill[$itemId] = $row;
        }
        foreach ($onlineData as $key => $row) {
            $itemId = $row['item_id'];
            if (isset($onSaleSeckill[$itemId]) && $onSaleSeckill[$itemId]['stock'] > 0) {//正在秒杀的商品库存>0,补贴列表不展示
                unset($onlineData[$key]);
            } else if (isset($allSeckill[$itemId]) && strtotime($allSeckill[$itemId]['begin_time']) > time()) {//秒杀未开始，补贴列表不展示
                unset($onlineData[$key]);
            } else {
                $onlineInfo = $this->getOnlineInfo($itemId);
                $onlineData[$key]['stock'] = $onlineInfo['stock'] ?? 0;
                $onlineData[$key]['open_wechat_mini_link'] = $this->getLink($row['original_link'], $row['wechat_mini_link'], $row['share_wechat_mini_link']);
                $onlineData[$key]['statSign'] = statSign::genStatSign(statSign::MODULE_SUBSIDY_DAY_BANNER, [
                    statSign::EXTEND_KEY_OBJ_ID => $row['alias'],
                    statSign::EXTEND_KEY_ACTIVITY_NAME => 'subsidy_day'
                ], ['activity_name' => 'subsidy_day', 'title' => $row['title'], 'act_from' => $this->actFrom]);
            }
        }

        $onSaleSeckill = array_values($onSaleSeckill);
        if ($onSaleSeckill) {
            shuffle($onSaleSeckill);
        }
        [$onSaleList, $allStock] = $this->formatOnSaleSeckill($onSaleSeckill);
        if (date('H') < 10) {
            $seckillStatus = 0;
        } else if (empty($allStock)) {
            $seckillStatus = 2;
        } else {
            $seckillStatus = 1;
        }
        $redisSeckill = new newCache(redisKeys::KEY_B_CACHE_SUPER_SUBSIDY_DAY_SUBSCRIBE);
        $subKeyPrefix = 'subscribe_seckill-' . $this->uid . '-' . date('Ymd', strtotime(date('Y-m-d')) + 86400);
        $subRes = $redisSeckill->getCache($subKeyPrefix);
        $isSubscribe = $subRes['subscribe'] ?? false;
        $isSubscribe = $isSubscribe ? true : false;


        $data = [
            'seckill_status' => $seckillStatus,//0：未开始，1：正在热抢 ，2：已抢光 10：00点开始
            'seckill_list' => [
                'on_sale' => $onSaleList,
                'tomorrow' => $this->formatTomorrowSeckill($tomorrowSeckill)
            ],
            'online_list' => $this->formatOnlineList($onlineData),
            'is_subscribe' => $isSubscribe ? 1 : 0,
        ];
        $this->setSuccess($data);
    }

    private function formatOnSaleSeckill($onSaleSeckill)
    {
        $allStock = 0;
        $arr = [];
        $posArr = [];
        $noStockArr = [];
        foreach ($onSaleSeckill as $row) {
            if (!$row['stock']) {
                $noStockArr[] = $row;
            } else if ($row['pos'] > 0) {
                $posArr[] = $row;
            } else {
                $arr[] = $row;
            }
            $allStock = $row['stock'] ? ($allStock + $row['stock']) : $allStock;
        }
        if ($posArr) {
            $sortPos = array_column($posArr, 'pos');
            $sortBegin = array_column($posArr, 'begin_time');
            array_multisort($sortPos, SORT_ASC, $sortBegin, SORT_DESC, $posArr);
            foreach ($posArr as $row) {
                $pos = $row['pos'];
                array_splice($arr, ($pos - 1), 0, [$row]);
            }
        }
        $arr = array_merge($arr, $noStockArr);
        return [$arr, $allStock];
    }

    private function formatTomorrowSeckill($tomorrowSeckill)
    {
        $arr = [];
        $posArr = [];
        foreach ($tomorrowSeckill as $row) {
            if ($row['pos'] > 0) {
                $posArr[] = $row;
            } else {
                $arr[] = $row;
            }
        }
        if ($posArr) {
            $sortPos = array_column($posArr, 'pos');
            array_multisort($sortPos, SORT_ASC, $posArr);
            foreach ($posArr as $row) {
                $pos = $row['pos'];
                array_splice($arr, ($pos - 1), 0, [$row]);
            }
        }
        return $arr;
    }

    private function formatOnlineList($onlineData)
    {
        $arr = [];
        $noStockArr = [];
        $posArr = [];
        foreach ($onlineData as $row) {
            if (!$row['stock']) {
                $noStockArr[] = $row;
            } else if ($row['pos'] > 0) {
                $posArr[] = $row;
            } else {
                $arr[] = $row;
            }
        }
        if ($posArr) {
            $sortPos = array_column($posArr, 'pos');
            array_multisort($sortPos, SORT_ASC, $posArr);
            foreach ($posArr as $row) {
                $pos = $row['pos'];
                array_splice($arr, ($pos - 1), 0, [$row]);
            }
        }
        return array_merge($arr, $noStockArr);
    }

    private function getLink($originalLink, $wechatMiniLink, $shareWechatMiniLink)
    {
        $wechatLink = $wechatMiniLink;
        if ($this->actFrom == 'share') {
            $wechatLink = $shareWechatMiniLink ? $shareWechatMiniLink : $wechatMiniLink;
        }
        $fallback = $originalLink ? 'niceliving://webview/normalscreen?protego=' . urlencode(base64_encode(json_encode(['url' => $originalLink]))) : '';
        $jsonData = [
            'id' => 'gh_396a6d2e73c5',
            'path' => $wechatLink,
            'fallback' => $fallback
        ];
        $open_wechat_mini_link = 'niceliving://open/wechat_miniprogram?protego=' . urlencode(base64_encode(json_encode($jsonData)));
        return $open_wechat_mini_link;
    }

    private function getSecKillInfo($secKillId)
    {
        $redis = new newCache(redisKeys::KEY_B_CACHE_SUPER_SUBSIDY_DAY_SECKILL_INFO);
        $info = $redis->getCache($secKillId);
        if (empty($info)) {
            $seckillInfo = Youzan::getSecKillInfo($secKillId);
            $info = [
                'seckill_id' => $secKillId,
                'stock' => 0,
            ];
            if ($seckillInfo) {
                $info['stock'] = $seckillInfo['total_current_stock'];
            }
            $redis->setCache($info, $secKillId);
            $redis->setExpireTime(60 * 60, $secKillId);//缓存秒杀商品库存 1个小时
        }
        return $info;
    }

    private function getOnlineInfo($itemId)
    {
        $redis = new newCache(redisKeys::KEY_B_CACHE_SUPER_SUBSIDY_DAY_ONLINE_INFO);
        $info = $redis->getCache($itemId);
        if (empty($info)) {
            $info = [
                'item_id' => $itemId,
                'stock' => 0,
            ];
            $goodsInfo = Youzan::getItemDeatil($itemId);
            if ($goodsInfo) {
                $info['stock'] = $goodsInfo['quantity'] ?? 0;//缓存商品库存 1个小时
            }
            $redis->setCache($info, $itemId);
            $redis->setExpireTime(60 * 60, $itemId);//缓存秒杀商品库存和时间 1个小时
        }
        return $info;
    }

}